[ORG 0x7c00] ;指定相对位置,即物理地址

[SECTION .text]
[BITS 16] ;位长
global _start

_start:
    ; 设置屏幕模式为文本模式，清除屏幕
    mov ax,3
    int 0x10

    mov ax,0
    mov ss,ax
    mov ds,ax
    mov es,ax
    mov sp,0x7c00

    mov si,msg
    call print

    ;读取硬盘
    mov edi,0x1000; 读取到的目标内存
    mov ecx,2; 起始扇区
    mov bl,4; 扇区数量

    call read_disk

    cmp word [0x1000],0x55aa
    jnz error
    jmp 0:0x1002
    jmp $

read_disk:
    ; 设置读写扇区的数量
    mov dx,0x1f2
    mov al,bl
    out dx,al

    inc dx
    mov al,cl;起始扇区的前八位
    out dx,al

    inc dx
    shr ecx,8
    mov al,cl;起始扇区的中八位
    out dx,al

    inc dx
    shr ecx,8
    mov al,cl;起始扇区的高八位
    out dx,al

    inc dx
    shr ecx,8
    and cl,0b1111;将高四位设为0

    mov al,0b1110_0000
    or al,cl
    out dx,al

    inc dx
    mov al,0x20;表示读取硬盘
    out dx,al

    xor ecx,ecx;清空ecx
    mov cl,bl;得到读写扇区的数量

    .read:
        push cx
        call .waits;等待数据准备完毕
        call .reads;读取扇区
        pop cx
        loop .read
    ret

.waits:
    mov dx,0x1f7
    .check:
        in al,dx
        jmp $+2;加上延迟
        jmp $+2
        jmp $+2
        and al,0b1000_1000
        cmp al,0b0000_1000
        jnz .check
    ret

.reads:
    mov dx,0x1f0
    mov cx,256;一个扇区256字
    .readw:
        in ax,dx
        jmp $+2
        jmp $+2
        jmp $+2
        mov [edi],ax
        add edi,2
        loop .readw
    ret
error:
    mov si,.msg
    call print
    hlt;让cpu停止
    jmp $
    .msg db "Booting error",10,13,0

print:
    mov ah,0x0e
    mov bh,0
    mov bl,0x01
    .loop:
        mov al,[si]
        cmp al,0
        jz .done
        int 0x10

        inc si
        jmp .loop
    .done:
        ret

msg:
    db "my first os,this name is ChenPuchu",10,13,0

times 510 - ($ - $$) db 0
db 0x55,0xaa
